package com.ding.easycontroller.service.impl;

import com.ding.easycontroller.dao.DaoDao;
import com.ding.easycontroller.exception.CheckException;
import com.ding.easycontroller.service.DaoService;
import com.ding.easycontroller.utils.IdStrategy;
import com.ding.easycontroller.work.Dao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.script.ScriptEngine;
import java.util.ArrayList;
import java.util.List;

@Service
public class DaoServiceImpl implements DaoService {


    @Autowired
    private DaoDao daoDao;

    private List<Dao> daos = new ArrayList<>();

    @Autowired
    private ScriptEngine scriptEngine;

    @Override
    public Dao getById(String id) {
        for (Dao dao : daos) {
            if (dao.getId().equals(id)) {
                return dao;
            }
        }
        return null;
    }

    private void check(Dao d) {
        for (Dao dao : daos) {
            if (dao.getName().equals(d.getName())) {
                throw new RuntimeException("重复创建仓库:" + dao.getName());
            }
        }
    }

    private void initDao(Dao dao) {
        dao.setScriptEngine(scriptEngine);
        try {
            dao.init();
        } catch (Exception e) {
            throw new CheckException(e);
        }

    }

    private void tryAdd(Dao dao) {
        check(dao);
        if (dao.getId() == null) {
            dao.setId(IdStrategy.createId(dao));
        }
        initDao(dao);
        daos.add(dao);
    }


    @Override
    public List<Dao> listAll() {
        return daos;
    }

    private Dao getByName(String name) {
        for (Dao dao : daos) {
            if (dao.getName().equals(name)) {
                return dao;
            }
        }
        return null;
    }

    @Override
    public void updateOrAdd(Dao dao) {
        if (dao.getId() != null) {
            Dao old = getByName(dao.getName());
            if (old != null) {
                throw new RuntimeException("不存在的服务:" + dao.getName());
            }
            tryUpdate(dao, old);
            daoDao.update(dao);
        } else {
            tryAdd(dao);
            daoDao.add(dao);
        }
    }

    private void tryUpdate(Dao dao, Dao old) {
        old.destroy();
        daos.remove(old);
        try {
            dao.setId(old.getId());
            tryAdd(dao);
        } catch (Exception e) {
            old.init();
            daos.add(old);
            throw e;
        }
    }

    @Override
    public void removeById(String id) {
        Dao dao = getById(id);
        if (dao == null) {
            return;
        }
        dao.destroy();
        daos.remove(dao);
        daoDao.removeById(id);
    }

    @Override
    public void init() {
        List<Dao> all = daoDao.listAll();
        for (Dao dao : all) {
            try {
                tryAdd(dao);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }


}
